package com.sample.dao;

import java.util.Date;

import com.google.common.base.Supplier;
import com.mongodb.BasicDBObject;
import com.mongodb.DBCollection;
import com.mongodb.DBObject;
import com.mongodb.MongoException;
import com.mongodb.WriteConcern;
import com.sample.core.Project;

/**
 * Gestion des projets en base.
 */
public class ProjectDao {
	
	/** Le nom du projet. */
	private static final String NAME = "name";
	/** La date du build.*/
	private static final String DATE_BUILD = "dateBuild";
	/** La description du projet.*/
	private static final String DESCRIPTION = "description";
	/** Le numero de version du projet.*/
	private static final String NUMERO_VERSION = "numeroVersion";
	
	/**
	 * La collection correspondant au projet.
	 */
	private Supplier<DBCollection> supplier;

	public ProjectDao() {
	}

	/**
	 * Insertion d'un projet sans attendre la reponse du serveur.
	 * @param project
	 * @throws MongoException
	 */
	public void insert(final Project project) throws MongoException{
		supplier.get().insert(WriteConcern.NONE, toDBObject(project));
		
	}
	
	/**
	 * @param name le nom du projet recherché
	 * @return le projet associé au nom.
	 */
	public Project get(final String name){
		final BasicDBObject result = (BasicDBObject) supplier.get().findOne(new BasicDBObject(NAME, name));
		return toProject(result);
	}

	/**
	 * Conversion d'un projet est objet DBObject
	 * @param project
	 * @return DBObject
	 */
	private static DBObject toDBObject(Project project) {
		final BasicDBObject dbObject = new BasicDBObject();
	    dbObject.put(NAME, project.getName());
	    dbObject.put(NUMERO_VERSION, project.getNumeroVersion());
	    dbObject.put(DATE_BUILD, project.getDateBuild());
	    dbObject.put(DESCRIPTION, project.getDescription());
	    return dbObject;
	}
	
	/**
	 * @param dbObject
	 * @return
	 */
	private static Project toProject(DBObject dbObject) {
		final Project project = new Project();
		project.setName((String) dbObject.get(NAME));
		project.setNumeroVersion((String) dbObject.get(NUMERO_VERSION));
		project.setDescription((String) dbObject.get(DESCRIPTION));
		project.setDateBuild((Date) dbObject.get(DATE_BUILD));
		return project;
	}
	
	/**
	 * Initialisation de l'index.
	 */
	public void init(){
		BasicDBObject basicDBObject = new BasicDBObject();
		basicDBObject.put("name", "index_name_project");
		basicDBObject.put("unique", Boolean.TRUE);
		basicDBObject.put("dropDups", Boolean.TRUE);
		this.supplier.get().ensureIndex(new BasicDBObject(NAME, 1), basicDBObject);
	}
	
	/**
	 * @param supplier l'acces à la collection des projets.
	 */
	public void setSupplier(Supplier<DBCollection> supplier) {
		this.supplier = supplier;
	}
}
